package com.exam.config;

import com.exam.Entity.CustomUserDetails;
import com.exam.Service.LoginService;
import com.exam.Service.LoginService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginService loginService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 返回一个不加密的 PasswordEncoder 实例
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .successHandler(authenticationSuccessHandler()) // 自定义登录成功处理
                .failureHandler(authenticationFailureHandler()) // 登录失败处理
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login")
                .permitAll();
    }

    private AuthenticationSuccessHandler authenticationSuccessHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=UTF-8");
            // 获取认证后的用户信息
            CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal();

            // 构造自定义响应对象
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("type", userDetails.getUserType());
            responseData.put("tno", userDetails.getTno());
            responseData.put("sno", userDetails.getSno());
            responseData.put("name", userDetails.getName());
            responseData.put("id", userDetails.getId());
            responseData.put("tname", userDetails.getTname());
            responseData.put("sname", userDetails.getSname());

            // 将响应内容写入
            response.getWriter().write(new ObjectMapper().writeValueAsString(responseData));
        };
    }
    private AuthenticationFailureHandler authenticationFailureHandler() {
        return (request, response, exception) -> {
            response.setContentType("application/json;charset=UTF-8");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 设置 HTTP 状态码为 401 (未授权)

            // 构造失败的响应数据
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("status", "error");
            responseData.put("message", "登录失败，用户名或密码错误");
            responseData.put("error", exception.getMessage());

            // 将响应内容写入
            response.getWriter().write(new ObjectMapper().writeValueAsString(responseData));
        };
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(username -> loginService.loadUserByUsername(username))
                .passwordEncoder(passwordEncoder());
    }
}
